/*
   Copyright 2009 Bégaudeau Stéphane

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
 */

package faneclipse.builder;

import faneclipse.editors.FanCodeScanner;

import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;

/**
 * This class has to find errors in a ".fan" file, and put marker on them.
 * @author BEGAUDEAU stephane
 */
public class FanFileChecker {
	/**
	 * The type of problem.
	 */
	private static final String MARKER_TYPE = "FanEclipse.Problem";
	
	/**
	 * The resource we are analizing.
	 */
	private IResource resource;
	
	/**
	 * The constructor.
	 * @param resource The resource we will analyse.
	 */
	public FanFileChecker(final IResource resource) {
		this.resource = resource;
	}
	
	/**
	 * @param file The IFile on which we will add a marker.
	 * @param message The message of the marker.
	 * @param lineNumber The number of the line on the file.
	 * @param severity The severity of the marker.
	 */
	private void addMarker(final IFile file, final String message, final int lineNumber, final int severity) {
		try 
		{
			IMarker marker = file.createMarker(MARKER_TYPE);
			marker.setAttribute(IMarker.MESSAGE, message);
			marker.setAttribute(IMarker.SEVERITY, severity);
			marker.setAttribute(IMarker.LINE_NUMBER, lineNumber);
		}
		catch (CoreException e)
		{
			e.printStackTrace();
		}
	}
	
	/**
	 * @param file The file on which we will delete all the marker.
	 */
	private void deleteMarkers(final IFile file) {
		try
		{
			file.deleteMarkers(MARKER_TYPE, false, IResource.DEPTH_ZERO);
		}
		catch (CoreException ce)
		{
			ce.printStackTrace();
		}
	}
	
	/**
	 * @return If the file is valid.
	 */
	public final boolean check() {
		boolean result = true;
		if (resource instanceof IFile && resource.getName().endsWith(".fan"))
		{
			IFile file = (IFile) resource;
			deleteMarkers(file);
			result = result && checkOpenClose(file);
		}
		return result;
	}
	
	/**
	 * @param file The file that we will check
	 * @return If the file is valid.
	 */
	private boolean checkOpenClose(final IFile file) {
		//FIXME Refactoring !!
		boolean result = true;
		
		File f = new File(file.getLocation().toOSString());
		if(f.exists())
		{
			try
			{
				Scanner sc = new Scanner(f);
				int cpt = 1;
				while(sc.hasNextLine())
				{
					String line = sc.nextLine();
					if(line.contains("//"))
					{
						int beginComments = line.indexOf("//");
						line = line.substring(0, beginComments);
					}
					if(line.contains("**"))
					{
						int beginComments = line.indexOf("**");
						line = line.substring(0, beginComments);
					}
					
					for(String keyword : FanCodeScanner.KEYWORD)
					{
						if(line.toLowerCase().contains(" "+keyword.toLowerCase()+" ") && !line.contains(" "+keyword+" "))
						{
							this.addMarker(file, "Invalid keyword case", cpt, IMarker.SEVERITY_ERROR);
						}
					}
					
					cpt++;
				}
			}
			catch (FileNotFoundException e)
			{
				e.printStackTrace();
			}
		}
		
		return result;
	}
}
